package ScalaStudy.chapter09plus

import ScalaStudy.chapter06.Person
import com.sun.org.apache.xpath.internal.functions.FuncUnparsedEntityURI

object Test03_Generics {
  def main(args: Array[String]): Unit = {


    //////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////  泛型  /////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////


    println("======================================")
    println("=============  协变和逆变  =============")
    println("======================================")
    println(" ")

    //定义带泛型的集合类型
    class MyCollection[+E] {}

    println("======== 虽然Parent和Child是父子关系，但是他们的集合是没有父子关系的，如果想保持关系，需要用协变，[+E] =====")
    val childList : MyCollection[Parent] = new MyCollection[Child]

    println("========   如果想要父类赋给子类，那么需要逆变，使用[-E]   =====")

//    class MyCollection[-E] {}
//    val childList : MyCollection[SubChild] = new MyCollection[Child]

    //定义继承关系

    class Parent {}
    class Child extends Parent {}
    class SubChild extends Child {}


    //////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////  泛型上下限  /////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////

    println(" ")
    println("======================================")
    println("=============  泛型上下限  =============")
    println("======================================")
    println(" ")

    println("1、泛型上下限概念介绍")

    class fatherList[T <: Person]  //当前T的类型不能超过Person的类型，可以是Person的子类，也可以是Person
    class fatherList1[T >: Person]  //当前T的类型超过Person的类型，可以是Person的父类，也可以是Person

    println("2、泛型上下限")

    def test[A <: Child](a: A): Unit = {    //定义一个类，第一个需要传入泛型，第二个传入泛型的参数
      println(a.getClass.getName)           //打印出泛型的类型
    }

    test[Child](new Child)
    test[Child](new SubChild)
    test[SubChild](new SubChild)
//    test[SubChild](new Child)        //不能把父类的对象赋给子类

    //////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////  泛型上下文限定  ///////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////

    println(" ")
    println("======================================")
    println("=============  上下文限定  =============")
    println("======================================")

//    def f[A:B](a:A) = println(a) //等同于 def f[A](a:A)(implicit arg:B[A]) = println(a)

    //A是泛型的名称
    //B是隐式参数的名称，这个隐式参数以A作为泛型


  }
}
